<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Key的作用</title>
</head>
<body>
    <div id="test"></div>
     <!-- 引入React核心库 -->
     <script src="../JS/new/react.development.js"></script>
     <!-- 引入ReactDOM，用于支持react操作DOM -->
     <script src="../JS/new/react-dom.development.js"></script>
     <!-- 引入babel 用于将书写的JSX语法 编译成JS语法 -->
     <script src="../JS/new/babel.min.js"></script>


    <!-- 
        经典面试题:
            1). react/vue中的key有什么作用 (key的内部原理是什么?)
            2). 为什么遍历列表时,key最好不要用 index

            1. 虚拟DOM中key的作用:
                1). 简单的说: key是虚拟DOM对象的标识,在更新显示时key起着极其重要的作用
                2). 详细的说: 当状态中的数据发生变化时,react会根据[新数据]生成[新的虚拟DOM]
                             随后react进行[新虚拟DOM]与[旧虚拟DOM]的diffing比较, 比较规则如下
                    a. 旧虚拟DOM中找到了与新虚拟DOM相同的key
                        (1). 若虚拟DOM中内容没变,直接使用之前的真实DOM
                        (2). 若虚拟DOM中内容变了,则生成新的真实DOM,随后替换掉页面中之前的真实DOM
                    b. 旧虚拟DOM中未找到与新虚拟DOM相同的key
                        根据新数据创建新的真实DOM,随后渲染到页面上                 
            2. 用index作为key可能会引发的问题
                1.若对数据进行:逆序添加,逆序删除,等破坏顺序操作:
                    会产生没有必要的真实DOM更新===>界面效果没问题,但效率低
                2.如果结构中还包含输入类DOM:
                    会产生错误DOM更新===>界面有问题
                3.注意!如果不存在对数据的逆序添加,删除等破坏顺序操作,
                    仅用于渲染列表用于展示,使用index作为key是没有问题的
            3. 开发中如何选择key?:
                1.最好使用每调数据的唯一标识作为key,比如id,手机号,身份证号,学号,等唯一值
                2.如果确定只是简单的数据展示,用index也是可以的
     -->






     <!-- 
        解释一下为什么不能用index

            慢动作回放----使用index索引值作为key

            初始数据:
                {id:1,name:'张三',age:18}
                {id:2,name:'Altria',age:14}
                {id:3,name:'王五',age:22}
            初始的虚拟DOM:
                <li key="0">张三---18</li>
                <li key="1">Altria---14</li>
                <li key="2">王五---22</li>
            更新后的数据:
                {id:4,name:'李四',age:13}
                {id:1,name:'张三',age:18}
                {id:2,name:'Altria',age:14}
                {id:3,name:'王五',age:22}
            更新数据后的虚拟DOM
                <li key="0">李四---13</li>
                <li key="1">张三---18</li>
                <li key="2">Altria---14</li>
                <li key="3">王五---22</li>
            因为 key 值变化了 所以 全都得重新渲染
            如果是两千调数据 那就得 重新 渲染两千零一条数据
            不过 加在数组后边 应该不会发生这种问题



            虚拟DOM input是没有 value值 这个属性的 ; 是 检测不到 input框中的 value值的
      -->
    <script type="text/babel">
        class Person extends React.Component{
            state={
                persons:[
                    {id:1,name:'张三',age:24},
                    {id:2,name:'Altria',age:14},
                    {id:3,name:'王五',age:22},
                ]
            }
            addPerson = ()=>{
                const {persons} = this.state
                const p = {id:persons.length+1,name:'李四',age:13}
                this.setState({
                    persons:[p,...persons]
                })
            }
            render(){
                return(
                    <div>
                        <h2>展示人员信息</h2>
                        <button onClick={this.addPerson}>添加一个人员信息</button>
                        <h3>使用Index(索引值)作为key</h3>
                        <ul>
                            {
                                this.state.persons.map((item,index)=>{
                                    return <li key={index}>
                                            {item.name} --- {item.age} <input type="text" />
                                        </li>
                                })
                            }
                        </ul>
                        <hr/>
                        <hr/>
                        <h3>使用id(数据的唯一标识)索引值作为key</h3>
                        <ul>
                            {
                                this.state.persons.map(item=> <li key={item.id}>{item.name} --- {item.age} <input type="text" /></li>)
                            }
                        </ul>
                    </div>
                )
            }
        }
        ReactDOM.render(<Person/>,document.getElementById('test'))

    </script>

</body>
</html>